/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MainClass;

import Connection.Conexao;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import MyExceptions.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;

/**
 *
 * @author Murilo
 */
public class Banco {
    private String Nome;
    private double Limite;
    private ArrayList<Conta> ListaContas;

    public Banco(String Nome) {
        this.Nome = Nome;
        this.ListaContas = new ArrayList();
        this.Limite = 1000;
    }

    public String getNome() {
        return Nome;
    }

    public void setNome(String Nome) {
        this.Nome = Nome;
    }

    public ArrayList<Conta> getListaContas() {
        return ListaContas;
    }

    public void setListaContas(ArrayList<Conta> ListaContas) {
        this.ListaContas = ListaContas;
    }

    public Banco() {
    }
    
    public int CriarConta(String Senha, double Saldo) throws Exception{
        int NumConta = (int)(Math.random() * 100);
        Connection conn;
        conn = Conexao.getInstancia().getConnection();
        PreparedStatement pstmt = null;
        String SQL = "INSERT INTO CONTA "
                + "(NUMERO_CONTA, SENHA, SALDO, ID_BANCO)"
                + "VALUES(?,?,?,1)";
        try{
            pstmt = conn.prepareStatement(SQL);
            pstmt.setInt(1, NumConta);
            pstmt.setString(2, Senha);
            pstmt.setDouble(3, Saldo);
            pstmt.execute();
        }catch(SQLException ex){
            throw new Exception("Houve um erro ao executar a instrucao SQL");
        }finally{
            Conexao.getInstancia().closeConnection(conn, pstmt, null);
        }
        return NumConta;
    }
    
    public void Saque(int NumeroConta, String Senha, double Valor)
            throws ExceptionContaInvalida, ExceptionValorMuitoAlto, ExceptionSaque, Exception{
        ArrayList<Conta> Lista = this.CarregarContas();
        int indiceObjeto = Lista.indexOf(new Conta(NumeroConta));
        
        if(indiceObjeto == -1){
            throw new ExceptionContaInvalida(NumeroConta, new Date());
        }
        
        if(Valor > this.Limite){
            throw new ExceptionValorMuitoAlto(Lista.get(indiceObjeto).getSaldo(), Valor, "Valor do Saque Maior que o Limite em Saldo.");
        }
        
        Conta C = Lista.get(indiceObjeto);
        C.Saque(Senha, Valor);
    }
    
    public double VerificaSaldo(int NumeroConta)
            throws ExceptionContaInvalida, Exception{
        ArrayList<Conta> Lista = this.CarregarContas();
        int indiceObjeto = Lista.indexOf(new Conta(NumeroConta));
        if(indiceObjeto == -1){
            throw new ExceptionContaInvalida(NumeroConta, new Date());
        }
        for(Conta conta : Lista){
            if(conta.getNumeroConta() == NumeroConta){
                return conta.getSaldo();
            }
        }
        return 0;
    }
    
    public double VerificaSaldo(int NumeroConta, String Senha)
            throws ExceptionContaInvalida, Exception{
        ArrayList<Conta> Lista = this.CarregarContas();
        int indiceObjeto = Lista.indexOf(new Conta(NumeroConta));
        if(indiceObjeto == -1){
            throw new ExceptionContaInvalida(NumeroConta, new Date());
        }
        if(!Senha.equals(Lista.get(indiceObjeto).getSenha())){
            throw new ExceptionSenhaInvalida(Senha, Senha.length(), new Date());
        }
        for(Conta conta : Lista){
            if(conta.getNumeroConta() == NumeroConta && conta.getSenha().equals(Senha)){
                return conta.getSaldo();
            }
        }
        return 0;
    }
    
    public ArrayList CarregarContas() throws Exception{
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        String SQL = "SELECT * FROM CONTA";
        ArrayList<Conta> lista = new ArrayList();
        try{
            conn = Conexao.getInstancia().getConnection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery(SQL);
            while(rs.next()){
                Conta ContaAux = new Conta();
                ContaAux.setNumeroConta(rs.getInt(2));
                ContaAux.setSenha(rs.getString(3));
                ContaAux.setSaldo(rs.getDouble(4));
                lista.add(ContaAux);
            }
        }catch(SQLException ex){
            throw new Exception("Houve um erro ao executar a instrucao SQL");
        }finally{
            Conexao.getInstancia().closeConnection(conn, stmt, rs);
        }
        return lista;
    }

}
